package com.hyt.it.ogt.kq.common.bm.enums.pay.nonTaxPay;


import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Signature;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.PKCS8EncodedKeySpec;
import java.security.spec.X509EncodedKeySpec;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

public class RSASignUtil {
    private static final String KEY_ALGORITHM = "RSA";
    private static final String SIGNATURE_ALGORITHM = "MD5withRSA";

    public RSASignUtil() {
    }

    public static String getPrivateKey() {
        return Configuration.getInstance().getValue("nonTaxPayPrivateKey");
    }

    public static String getPublicKey() {
        return Configuration.getInstance().getValue("nonTaxPayPublicKey");
    }

    public static String getMerapp() {
        return Configuration.getInstance().getValue("nonTaxPayMerapp");
    }
    public static String getVersion() {
        return Configuration.getInstance().getValue("nonTaxPayVersion");
    }

    /**
     * 签名
     * @param params
     * @param privateKey
     * @return
     */
    public static String newRSASign(Map<String, String> params, String privateKey) {
        params = paraFilter(params);
        String paramsStr = createLinkString(params);
        return sign(paramsStr, privateKey);
    }

    /**
     * 验证签名
     * @param params
     * @param publicKey
     * @param sign
     * @return
     */
    public static boolean verfityRSASign(Map<String, String> params, String publicKey, String sign) {
        params = paraFilter(params);
        String paramsStr = createLinkString(params);
        return verifySign(paramsStr, publicKey, sign);
    }

    public static Map<String, String> paraFilter(Map<String, String> params) {
        Map<String, String> result = new HashMap();
        if (params != null && params.size() > 0) {
            Iterator var3 = params.keySet().iterator();

            while(var3.hasNext()) {
                String key = (String)var3.next();
                String value = (String)params.get(key);
                if (value != null && !value.equals("") && !key.equalsIgnoreCase("sign")) {
                    result.put(key, value);
                }
            }

            return result;
        } else {
            return result;
        }
    }

    public static String createLinkString(Map<String, String> params) {
        List<String> keys = new ArrayList(params.keySet());
        Collections.sort(keys);
        String prestr = "";

        for(int i = 0; i < keys.size(); ++i) {
            String key = (String)keys.get(i);
            String value = (String)params.get(key);
            prestr = prestr + key + "=" + value + "&";
        }

        if (prestr.length() > 1) {
            prestr = prestr.substring(0, prestr.length() - 1);
        }

        return prestr;
    }

    public static String sign(String data, String privateKey) {
        try {
            return sign(data.getBytes(CharType.UTF8.value), privateKey);
        } catch (Exception var4) {
            var4.printStackTrace();
            throw new IllegalAccessError("生成密钥签名失败");
        }
    }

    private static String sign(byte[] data, String privateKey) {
        try {
            byte[] keyBytes = BsBase64Util.decodeBase64(privateKey);
            PKCS8EncodedKeySpec pkcs8KeySpec = new PKCS8EncodedKeySpec(keyBytes);
            KeyFactory keyFactory = KeyFactory.getInstance("RSA");
            PrivateKey priKey = keyFactory.generatePrivate(pkcs8KeySpec);
            Signature signature = Signature.getInstance("MD5withRSA");
            signature.initSign(priKey);
            signature.update(data);
            return BsBase64Util.encodeBase64String(BsBase64Util.encodeBase64String(signature.sign()));
        } catch (Exception var8) {
            var8.printStackTrace();
            throw new IllegalAccessError("生成密钥签名失败");
        }
    }

    public static boolean verifySign(String data, String publicKey, String sign) {
        if (data != null && data.trim().length() != 0) {
            if (publicKey != null && publicKey.trim().length() != 0) {
                if (sign != null && sign.trim().length() != 0) {
                    try {
                        return verifySign(data.getBytes(CharType.UTF8.value), BsBase64Util.decodeBase64(publicKey), BsBase64Util.decodeBase64(BsBase64Util.decodeBase64(sign)));
                    } catch (Exception var4) {
                        var4.printStackTrace();
                        return false;
                    }
                } else {
                    return false;
                }
            } else {
                return false;
            }
        } else {
            return false;
        }
    }

    public static boolean verifySign(byte[] data, byte[] publicKey, byte[] sign) throws Exception {
        X509EncodedKeySpec keySpec = new X509EncodedKeySpec(publicKey);
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        keyFactory = KeyFactory.getInstance("RSA");
        PublicKey pubKey = keyFactory.generatePublic(keySpec);
        Signature signature = Signature.getInstance("MD5withRSA");
        signature.initVerify(pubKey);
        signature.update(data);
        return signature.verify(sign);
    }


    /**
     * 获取公钥
     *
     * @param publicKeyBase64 公钥的 Base64 字符串
     * @return: {@link PublicKey }
     * @author: mengz
     * @time: 2019/11/5 16:59
     */
    public static PublicKey getPublicKey(String publicKeyBase64)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        X509EncodedKeySpec pubKeySpec = new X509EncodedKeySpec(BsBase64Util.decodeBase64(publicKeyBase64));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PublicKey publicKey = keyFactory.generatePublic(pubKeySpec);
        return publicKey;
    }

    /**
     * 获取私钥
     *
     * @param privateKeyBase64 私钥的 Base64 字符串
     * @return: {@link PrivateKey }
     * @author: mengz
     * @time: 2019/11/5 16:59
     */
    public static PrivateKey getPrivateKey(String privateKeyBase64)
            throws NoSuchAlgorithmException, InvalidKeySpecException {
        PKCS8EncodedKeySpec priKeySpec = new PKCS8EncodedKeySpec(BsBase64Util.decodeBase64(privateKeyBase64));
        KeyFactory keyFactory = KeyFactory.getInstance("RSA");
        PrivateKey priKey = keyFactory.generatePrivate(priKeySpec);
        return priKey;
    }

    // 解析请求参数
    public Map<String, String> prase(String paramsQueryString) {
        Map<String, String> maps = new HashMap<>();
        String[] params = paramsQueryString.split("\\&");
        for (String param : params) {
            String[] keyValue = param.split("=");
            if (keyValue.length == 1) {
                maps.put(keyValue[0], "");
            }
            if (keyValue.length == 2) {
                maps.put(keyValue[0], keyValue[1]);
            }
        }
        return maps;
    }

}
